package ua.org.cityid.server.DA;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import ua.org.cityid.client.actions.GetCities;
import ua.org.cityid.client.actions.GetCitiesCount;
import ua.org.cityid.client.actions.GetCitiesCountResult;
import ua.org.cityid.client.actions.GetCitiesResult;
import ua.org.cityid.server.PMF;
import ua.org.cityid.shared.data.City;

import com.google.inject.Inject;

public class CityDA {

	@Inject
	public CityDA(){}
	
	public City addCity(City city) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
        try {
            pm.makePersistent(city);
        } finally {
            pm.close();
        }
        return city;
	}

	public GetCitiesCountResult getCitiesCount(GetCitiesCount params) {
//		LoadCitiesFromFile(params.getRegionId());
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query query = pm.newQuery(City.class);
		query.setResult("count(regionId)");
		query.declareParameters("int regionIdParam");
		query.setFilter("regionId == regionIdParam");
		Integer citiesCount = (Integer) query.execute(params.getRegionId());
		return new GetCitiesCountResult(params.getRegionId(), citiesCount);
	}
	
	public GetCitiesResult getCities(GetCities params) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query query = pm.newQuery(City.class);
		query.setFilter("regionId == regionIdParam");
		query.setOrdering("name asc");
		query.declareParameters("int regionIdParam");
		query.setRange((long)params.getStartFrom(), params.getStartFrom()+(long)params.getMaxItems());
		System.out.println("Query " + query.toString());
		List<City> response = (List<City>) query.execute(params.getRegionId());
		ArrayList<City> cities = copyCities(response);
		GetCitiesResult result = new GetCitiesResult(cities);
		query.closeAll();
		pm.close();
		return result;
	}

	private ArrayList<City> copyCities(List<City> response) {
		ArrayList<City> cities = new ArrayList<City>();
		for (City c : response){
			City newc = new City(c.getId(), c.getRegionId(), c.getName());
			ArrayList<Integer> zips = new ArrayList<Integer>(); 
			for (Integer zip : c.getZipCodes()) {
				zips.add(zip);
			}
			newc.setPhoneCode(c.getPhoneCode());
			newc.setZipCodes(zips);
			cities.add(newc);
		}
		return cities;
	}
	
	public void LoadCitiesFromFile(int regionIdToLoad) {
		File f1 = new File("cities.txt");
		FileInputStream in = null;
		BufferedReader input = null;
		try {
			in = new FileInputStream(f1);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		try {
			input = new BufferedReader(new InputStreamReader(in, "UTF-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		ArrayList<City> cities = new ArrayList<City>();
		String line = null;
		try {
			while ((line = input.readLine()) != null) {
				String cityInfo [] = line.split(",");
				
				Long cityId  = Long.parseLong(cityInfo[0]);
				int regionId = Integer.parseInt(cityInfo[1]) - 1;
//				if (regionIdToLoad != regionId)
//					continue;
				
				String cityName = cityInfo[2];
				City newCity = new City(cityId, regionId, cityName);
				if (cityInfo.length == 4) {
					int phoneCode = Integer.parseInt(cityInfo[3]);
					newCity.setPhoneCode(phoneCode);
				}
				cities.add(newCity);
				System.out.println("Creating City #"+ cityId + " in region # " + regionId + " name is \"" + cityName);
			}
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		addCityBulk(cities);
	}
	
	public void addCityBulk(ArrayList<City> cityList) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
        try {
        	for (City c : cityList){
        		pm.makePersistent(c);
        	}
        } finally {
            pm.close();
        }
	}
}
